﻿using FPSO.HMI.Controls;
using FPSO.HMI.Task;
using FPSO.HMI.Utils;
using FPSO.HMI.Views.Dialog;
using FPSO.Models.Constant;
using FPSO.Models.Domain;
using FPSO.Models.TagMapping;
using FPSO.Models.ViewModel.Controls;
using FPSO.Services;
using FPSO.Services.Impl;
using MySql.Data.MySqlClient;
using Newtonsoft.Json;
using NSubstitute.Core;
using OpcUaHelper;
using PDB.DotNetSDK;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Diagnostics;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;

namespace FPSO.HMI.Views
{
    /// <summary>
    /// MainView.xaml 的交互逻辑
    /// </summary>
    public partial class MainView : Window
    {
        private TaskManageView taskManageView;
        private ExecuteView executeView;
        private OutAndSwapView outAndSwapView;
        private OPCMonitorView opcMonitorView;
		private OPCTimeLineMonitorView opcTimeLineView;
		private MonitorView monitorView;
        private StatusMonitorView statusMonitorView;

        private IDataBindingService bindingService;
        private TankVolumeViewModel volumeViewModel;
        private Thread calcThread;
		//记录实测的实船和舱室信息，并通过ShipTankStatusLog记录到对应数据库中
		//private Thread realTimeThread;

		private const int SW_HIDE = 0;
		private const int SW_NORMAL = 1;
		private const int SW_MAXIMIZE = 3;
		private const int SW_SHOWNOACTIVATE = 4;
		private const int SW_SHOW = 5;
		private const int SW_MINIMIZE = 6;
		private const int SW_RESTORE = 9;
		private const int SW_SHOWDEFAULT = 10;

        [DllImport("User32.dll")]
		private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
		public MainView()
        {
			string output = string.Empty;
			//在系统启动之前先检查运行环境是否满足要求
			bool check = SysEnvironmentCheck();
			if (check == false)
			{
				output = "运行环境检查未通过，即将关闭！";
				System.Windows.MessageBox.Show(output);
				Application.Current.Shutdown();
				return;
			}
			//用户权限检查，可通过g_OnboardPreCheck控制是否需要检查
			if (TankConstant.g_OnboardPreCheck)
			{
				LoginDialog loginDialog = new LoginDialog();
				if (loginDialog.ShowDialog() == false)
				{
					// 退出登录时也退出程序
					Application.Current.Shutdown();
					return;
				}
			}

			try
			{
				if (App.UaClient == null && TankConstant.g_Onboard)
				{
					App.UaClient = new OpcUaClient();
					App.UaClient.ConnectServer(SysConfig.OPCConnStr, SysConfig.OPCBackupConnStr).Wait();
				}
			}
			catch (Exception ex)
			{
				output = "连接Opc服务器失败，即将离线运行！";
				System.Windows.MessageBox.Show(output);
				App.UaClient.Disconnect();
				App.UaClient = null;
				output = string.Empty;
				//return;
			}

			// 默认设为管理员权限
			AuthUtil.SetLoginStatus(1);
            AuthUtil.SetLoginUser("admin");

			InitializeComponent();

            btnClose.Click += (s, e) =>
            {
                var dialgoResult = MessageBox.Show("确定退出系统?", "提示", MessageBoxButton.YesNo);
                if (dialgoResult == MessageBoxResult.Yes)
                {
					if(App.UaClient != null)
					{
						App.UaClient.Disconnect();
						App.UaClient = null;
					}
					Close();
                }
            };

			this.Closing += Window_Closing;

			//暂时不启用PDB
			volumeViewModel = new TankVolumeViewModel();
			bindingService = new RealDataBindingServiceImpl<TankVolumeViewModel>(SysConfig.PDBConnStr, volumeViewModel);

			if (TankConstant.g_Onboard)
			{
				MainMenu.CargoMonitorBtn.Visibility = Visibility.Visible;
				MainMenu.BallastMonitorBtn.Visibility = Visibility.Visible;
				MainMenu.TaskManageBtn.Visibility = Visibility.Hidden;
				MainMenu.CommStatusBtn.Visibility = Visibility.Visible;
				MainMenu.OpcMonitorBtn.Visibility = Visibility.Visible;

				executeView = new ExecuteView();
				outAndSwapView = null;
				taskManageView = null;
				opcMonitorView = null;
				opcTimeLineView = null;
				monitorView = null;
				mainContent.Content = executeView;

				//NOTICE 调试版本把这部分定时刷新的界面功能封掉
				calcThread = new Thread(CalcTask);
				calcThread.IsBackground = true;
				calcThread.Start();
			}
			else
			{
				MainMenu.CargoMonitorBtn.Visibility = Visibility.Hidden;
				MainMenu.BallastMonitorBtn.Visibility = Visibility.Hidden;
				MainMenu.TaskManageBtn.Visibility = Visibility.Visible;
				MainMenu.CommStatusBtn.Visibility = Visibility.Hidden;
				MainMenu.OpcMonitorBtn.Visibility = Visibility.Hidden;

				taskManageView = new TaskManageView();
				executeView = null;
				outAndSwapView = null;
				opcMonitorView = null;
				opcTimeLineView = null;
				monitorView = null;
				mainContent.Content = taskManageView;
			}

			//if (!TankConstant.g_Onboard)
			//{
			//	realTimeThread = new Thread(RealTimeTask);
			//	realTimeThread.IsBackground = true;
			//	realTimeThread.Start();
			//}

			//TaskImpl.GetInstance();
		}

		private void Window_Closing(object sender, CancelEventArgs e)
		{
			if(MessageBox.Show("是否确认退出？","确认",MessageBoxButton.YesNo) == MessageBoxResult.Yes)
			{
				e.Cancel = false;
				if (App.UaClient != null)
				{
					App.UaClient.Disconnect();
					App.UaClient = null;
				}
			}
			else
			{
				e.Cancel = true;
			}
		}

		private void CalcTask()
        {
            while(true)
            {
                try
                {
                    bindingService.ReflushData(DateTime.Now);
                    SafeLoadAlgorithmService algorithmService = SafeLoadAlgorithmService.GetInstance();
                    Dictionary<string, double> levelDic = volumeViewModel.GetTankLevelDic();

					//Dictionary<int, double> fullDic = algorithmService.GetLevelDicByVolumDic(levelDic);
					//Dictionary<int, double> volumDic = volumeViewModel.GetTankVolumDic();
					//Dictionary<int, double> fullDic = algorithmService.GetFullDicByVolumDic(volumDic);
					//ManualCalcResult calcResult = algorithmService.CallManualCalc(fullDic);
					ManualCalcResult calcResult = algorithmService.CallManualCalc(levelDic,2);
                    if (calcResult != null)
					{
						//显示数据分为直接显示接收数据和显示计算返回的数据两部分，后者必须要接入safeload后台
						ShipDraught realDraught = volumeViewModel.GetRealDraught();
						ShipDraught calcDraught = calcResult.GetCalcDraught();
                        if (executeView != null)
                        {

							executeView.SetShipDraught(calcDraught, realDraught);
							executeView.SetTankStatus(calcResult);
							//executeView.SetOtherTankStatus(calcResult);
							// 去除监控图
							//executeView.AddCurveData(DateTime.Now, calcResult.ShipCalc.MaxPersf, calcResult.ShipCalc.MaxPerbm);
                        }
                        if (outAndSwapView != null)
                        {
                            outAndSwapView.SetShipDraught(calcDraught, realDraught);
							outAndSwapView.SetTankStatus(calcResult);  //待测试，这里刷新的是第一个界面？外输&倒舱界面舱室状态也要刷新

							ShipCalcState shipCalcState = calcResult.ShipCalc;
							outAndSwapView.AddStrengthData(shipCalcState.MaxPersf, shipCalcState.MaxPerbm);

							double calc_mid_draft = (calcDraught.MidPDraft + calcDraught.MidSDraft) / 2;
							double real_mid_draft = (realDraught.MidPDraft + realDraught.MidSDraft) / 2;
							outAndSwapView.AddDraftLineData(calc_mid_draft, real_mid_draft);
							outAndSwapView.AddHeelTrimData(shipCalcState.Heel, shipCalcState.Trim);
							outAndSwapView.AddStabilityData(shipCalcState.GM);
						}
					}
				}
                catch(Exception ex)
                { 
				}

                Thread.Sleep(1500);
            }
        }

		private void RealTimeTask()
		{
			while (true)
			{
				try
				{
					ShipDraught realDraught = volumeViewModel.GetRealDraught();
					Dictionary<string, double> levelDic = volumeViewModel.GetTankLevelDic();

					string shipstatus = JsonConvert.SerializeObject(realDraught);
					string tankstatus = JsonConvert.SerializeObject(levelDic);

					ShipTankStatusLog logout = new ShipTankStatusLog();
					logout.ShipStatus = shipstatus;
					logout.CargoTankStatus = tankstatus;
					SysConfig.g_ShipTankStatusLogService.AddShipTankStatusLog(logout);

					//删除当前数据库所有数据，通过计数判断是否需要备份
					if (SysConfig.g_ShipTankStatusLogService.GetDataCount() > 10)
					{
						foreach(ShipTankStatusLog shipTankStatusLog in SysConfig.g_ShipTankStatusLogService.GetAllLogs())
						{
							ShipTankStatusBackupLog shipTankStatusBackupLog = new ShipTankStatusBackupLog();
							shipTankStatusBackupLog.ShipStatus = shipTankStatusLog.ShipStatus;
							shipTankStatusBackupLog.CargoTankStatus = shipTankStatusLog.CargoTankStatus;
							shipTankStatusBackupLog.BallastTankStatus = shipTankStatusLog.BallastTankStatus;
							shipTankStatusBackupLog.OtherTankStatus = shipTankStatusLog.OtherTankStatus;
							shipTankStatusBackupLog.LogUpdateTime = shipTankStatusLog.LogUpdateTime;
							SysConfig.g_ShipTankStatusBackupLogService.AddShipTankStatusLog(shipTankStatusBackupLog);
						}
						SysConfig.g_ShipTankStatusLogService.FlushDatas();
					}
				}
				catch (Exception ex)
				{
				}
				Thread.Sleep(10000);
			}
		}

		private void WindowMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                DragMove();
            }
        }

		private void ShowExecute_Click(object sender, RoutedEventArgs e)
        {
            if (!(mainContent.Content is ExecuteView))
            {
                mainContent.Content = new ExecuteView();
            }
        }
        private void ShowTaskManage_Click(object sender, RoutedEventArgs e)
        {
            if (!(mainContent.Content is TaskManageView))
            {
                mainContent.Content = new TaskManageView();
            }
        }

        private void ShowMonitor_Click(object sender, RoutedEventArgs e)
        {
            if (!(mainContent.Content is MonitorView))
            {
                mainContent.Content = new MonitorView();
            }
        }

        private void ShowTaskMonitor_Click(object sender, RoutedEventArgs e)
        {
            if (!(mainContent.Content is UCTaskMonitor))
            {
                mainContent.Content = new UCTaskMonitor();
            }
        }

		private bool SysEnvironmentCheck()
		{
			if (TankConstant.MyLog == null)
				TankConstant.MyLog = new logs();
			//if (TankConstant.MyDataLog == null)
			//	TankConstant.MyDataLog = new logs(TankConstant.datalogSaveFilePath);

			bool m_safeloadboot = true;
			bool m_mysqlboot = true;
			//暂时封掉部分检查项目
			if(TankConstant.g_OnboardPreCheck)
			{
				string processName = "SafeLoad";
				Process[] processes = Process.GetProcessesByName(processName);
				if (processes.Length == 0)
				{
					try
					{
						Process.Start(SysConfig.SafeLoad_path);
					}
					catch { }
					m_safeloadboot = true;
				}
				else
					m_safeloadboot = true;

				string ConnectionString = ConfigurationManager.AppSettings["MySQLStr"];
				MySqlConnection conn = new MySqlConnection(ConnectionString);
				try
				{
					conn.Open();
					m_mysqlboot = true;
				}
				catch (Exception ex)
				{
					m_mysqlboot = false;
				}
			}

			//bool m_pdbboot = false;
			//PDBConnection conn1 = new PDBConnection(SysConfig.PDBConnStr);
			//try
			//{
			//	conn1.Open();
			//	m_pdbboot = true;
			//}
			//catch (Exception ex)
			//{
			//	m_pdbboot = false;
			//}

			string output = "";
			if (m_safeloadboot == true && m_mysqlboot == true/* && m_pdbboot == true*/)
			{
				output = "系统运行环境配置成功！";
				// 成功就不提示了，加快启动速度
				//System.Windows.MessageBox.Show(output);
				return true;

			}
			else
			{
				if (m_safeloadboot == false)
					output += "配载计算模块加载失败！\r\n";
				if (m_mysqlboot == false)
					output += "MySql数据库加载失败！\r\n";
				//if (m_pdbboot == false)
				//	output += "时序数据库加载失败！\r\n";
				System.Windows.MessageBox.Show(output);
				return false;
			}
		}
		private void UCMenu_OnMenuChanged(int menuPos)
		{
			string contentType = Convert.ToString(mainContent.Content.GetType());
			switch (menuPos)
			{
				case 0:// "货油舱监控":
					if (executeView == null)
					{
						executeView = new ExecuteView();
					}
                    executeView.ReloadTaskQueue();
					mainContent.Content = executeView;
					break;
				case 1:// "外输&倒舱":
					if (outAndSwapView == null)
					{
						outAndSwapView = new OutAndSwapView();
					}
                    outAndSwapView.ReloadTaskQueue();
                    mainContent.Content = outAndSwapView;
					break;
				case 2:// "任务管理":
					if (taskManageView == null)
					{
						taskManageView = new TaskManageView();
					}
                    taskManageView.ReloadTaskQueue();
                    mainContent.Content = taskManageView;
					break;
				case 3:// "通讯监控":
					if (monitorView == null)
					{
						monitorView = new MonitorView();
					}
					mainContent.Content = monitorView;
					break;
				case 4:// "任务监控":
					if (opcTimeLineView == null)
					{
						opcTimeLineView = new OPCTimeLineMonitorView();
					}
					mainContent.Content = opcTimeLineView;
					break;
				case 5:// "OPC点监控":
					if (opcMonitorView == null)
					{
						opcMonitorView = new OPCMonitorView();
					}
					mainContent.Content = opcMonitorView;
					break;
				//case 6:// "状态监测":
				//	if (statusMonitorView == null)
				//	{
				//		statusMonitorView = new StatusMonitorView();
				//	}
				//	mainContent.Content = statusMonitorView;
				//	break;
			}
        }
	}
}
